package thoughtworks.test;

/*
 * This class is used to convert a roman letter to number
 */

import java.util.ArrayList;
import java.util.List;

public class RomanToNumberConversion {
	
	//This list is used to store the number value for respective roman letter 
	private List<Integer> valArr; 
	
	//This method is used to validate the roman letter
	private void checkValidRomanString(String romanValue)
			throws InvalidRomanException {
		valArr = new ArrayList<Integer>();
		for (char letter : romanValue.toCharArray()) {
			if ("IVXLCDM".indexOf(letter) != -1) {
				valArr.add(ConstantsUtil.romanValues.get(new Character(letter)
						.toString()));
			} else {
				throw new InvalidRomanException("INVALID ROMAN NUMERAL.");
			}
		}
		for (String literal : ConstantsUtil.invalidCombinations) {
			if (romanValue.indexOf(literal) != -1) {
				throw new InvalidRomanException("INVALID ROMAN NUMERAL.");
			}
		}
	}

	//This method is used to check substraction rules for the roman letter
	private void checkSubtractionRules(int a, int b)
			throws InvalidRomanException {
		if (b == ConstantsUtil.romanValues.get("V")
				|| b == ConstantsUtil.romanValues.get("L")
				|| b == ConstantsUtil.romanValues.get("D")) {
			throw new InvalidRomanException("INVALID ROMAN NUMERAL.");
		} else {
			if (!(a == (b * 5) || a == (b * 10)))
				throw new InvalidRomanException("INVALID ROMAN NUMERAL.");
		}
	}

	public int convertRomanNumeral(String romanNumeral)
			throws InvalidRomanException {
		checkValidRomanString(romanNumeral);
		int numericValue = 0;
		try {
			for (int i = valArr.size() - 1; i >= 0; i--) {
				if (i != 0 && valArr.get(i) > valArr.get(i - 1)) {
					if (i!=1 && valArr.get(i) > valArr.get(i - 2)) {
						throw new InvalidRomanException("INVALID ROMAN NUMERAL.");
					} else {
						checkSubtractionRules(valArr.get(i), valArr.get(i - 1));
						numericValue += (valArr.get(i) - valArr.get(i-1));
						i--;
					}
				} else {
					numericValue += valArr.get(i);
				}
			}
			return numericValue;
		} catch (InvalidRomanException exception) {
			throw new InvalidRomanException(exception.getMessage());
		}
	}

}
